2023/12/234112字符

性能优化

页面级优化

  • 雪碧图、使用(data:url)、代码压缩合并分包,减少 HTTP 请求;
  • 预加载资源:preload;
  • CDN 加载资源;
  • DNS 预解析;

文件压缩

  • webpack:
const CompressionPlugin = require('compression-webpack-plugin');
const FontminPlugin = require('fontmin-webpack');

module.exports = {
    plugins: [
        new CompressionPlugin(),
        new FontminPlugin({  // 字体压缩
            autodetect: true, // 自动从CSS中提取unicode字符
            glyphs: ['\uf0c8' /* 要包含的额外符号 */],
        })
  ],
}
  • node:
const compression = require('compression');

app.use(compression());  // 在其他中间件前使用

抽离公共文件

splitChunks

代码级优化

  • 虚拟 DOM(减少 DOM 操作);
  • 尽量仅改动元素属性,尽量移动元素,而不是删除和创建;
  • 在滚动刷新时需要删除/添加 DOM 时,保证 DOM 数量不变,页面就不会卡顿;
  • 白屏 loading 动画;
  • 异步加载(defer、async);
  • 减少事件绑定(e.target);
  • H5 API requestAnimationFrame 代替定时器;
  • 节流与防抖;
  • 减少重绘与重排,CSS 开启 GPU 加速渲染;
  • 数据缓存:storage、cookie、封装缓存对象,后端 redis 缓存;
  • 减少 cookie 储存的东西,cookie 传输会浪费宽带。

节流与防抖

  • 节流:减少执行频率(页面滚动、窗口调整,抢购疯狂点击)
function throttle (fn, wait) {
    let lastTime = 0;
    return function () {
        let nowTime = new Data().getTime();
        if (nowTime - lastTime > wait) {
            fn();
            lastTime = nowTime;
        }
    }
}
  • 防抖:多次执行后,只执行一次(实时搜索,拖拽)
function debounce (fn, wait) {
    let timeout = null;
    return function () {
        if (timeout != null) clearTimeout(timeout);
        timeout = setTimeout(fn, wait);
    }
}

Vue 优化

  1. 尽量减少data中的数据,data 中的数据都会增加 getter 和 setter,会收集对应的 watcher;
  2. 冻结对象:Object.frozen(obj) 保持对象引用稳定;
  3. 使用 key 值做唯一标识;
  4. 尽可能的使用计算属性;
  5. 针对场景选择使用 v-show / v-if;
  6. 如果需要使用v-for给每项元素绑定事件时使用事件代理;
  7. 非实时绑定表单:减少 v-model 触发的数据更新导致的页面重绘重排(JS 执行线程与浏览器渲染线是互斥的);
  8. SPA 页面采用keep-alive缓存组件;
  9. 使用路由懒加载、异步组件;
  10. 数据缓存:请求对象放置状态树,优先从状态树获取数据(SSR);
  11. 骨架屏;
  12. PWA 页面本地存储。

React 优化

  1. 使用 return null 而不是 CSS 的 display: none 来控制节点的显示隐藏。保证同一时间页面的DOM节点尽可能的少;
  2. propsstate 的数据尽可能简单明了,扁平化;
  3. 不要使用数组下标作为key 利用 shouldComponentUpdatePureComponent 避免过多 render function
    • render 里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。 尽量将 propsstate 扁平化,只传递 component 需要的 props(传得太多,或者层次传得太深,都会加重shouldComponentUpdate里面的数据比较负担),慎将 component 当作 props 传入。
  4. 使用 babel-plugin-import 优化业务组件的引入,实现按需加载 使用 SplitChunksPlugin 拆分公共代码 使用动态 import,懒加载 React 组件。

渲染优化方案

  • 延迟分批装载渲染:分帧;
  • 长列表优化:数据庞大,减少 dom 重绘重排。

怎么看待性能优化

优化原则不是绝对的,对于不同的场景使用不同的侧重点,要针对项目的规模和类型进行适度的优化,不能盲目的追求标准和最佳实践。